package com.ruoyi.materialCuttingPlan.utils;


import com.ezylang.evalex.EvaluationException;
import com.ezylang.evalex.Expression;
import com.ezylang.evalex.parser.ParseException;
import com.ruoyi.common.utils.file.ImageUtils;
import com.ruoyi.materialCuttingPlan.domain.McpMaterialResults;
import com.ruoyi.materialCuttingPlan.domain.McpProjects;
import com.ruoyi.materialCuttingPlan.domain.McpWindows;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

public class CuttingPlanExcelUtil {
    protected static final Logger logger = LoggerFactory.getLogger(CuttingPlanExcelUtil.class);

    public static void exportCuttingPlan(Map<String, Object> projectInfo,
                                         String windowTitle,
                                         List<Map<String, Object>> materialData,
                                         HttpServletResponse response) throws IOException {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("切割方案");

        int rowNum = 0;

        // 上部：项目信息
        for (Map.Entry<String, Object> entry : projectInfo.entrySet()) {
            Row row = sheet.createRow(rowNum++);
            Cell keyCell = row.createCell(0);
            keyCell.setCellValue(entry.getKey());

            Cell valueCell = row.createCell(1);
            if ("门窗类型".equals(entry.getKey())) {
                String imagePath = (String) entry.getValue(); // 获取图片路径
                byte[] imageData = ImageUtils.readFile(imagePath);
                if (imageData == null) continue;
                int pictureIdx = workbook.addPicture(imageData, Workbook.PICTURE_TYPE_PNG);
                CreationHelper helper = workbook.getCreationHelper();
                Drawing<?> drawing = sheet.createDrawingPatriarch();

                ClientAnchor anchor = helper.createClientAnchor();
                anchor.setCol1(1);             // 第二列开始
                anchor.setCol2(3);             // 占据两列宽度
                anchor.setRow1(rowNum - 1);    // 当前行
                anchor.setDx1(20);             // 左边偏移 20 像素 ✅

                Picture picture = drawing.createPicture(anchor, pictureIdx);

                // ✅ 使用 scale 控制大小，保留偏移
                double scaleX = 0.9;  // 缩放为原来的 80%
                double scaleY = 1;
                picture.resize(scaleX, scaleY); // 不会清空 dx/dy

                sheet.getRow(rowNum - 1).setHeightInPoints(100);


            } else {
                if (entry.getValue() != null) {
                    valueCell.setCellValue(entry.getValue().toString());
                }
            }
        }

        // 中间部分：门窗备份
        rowNum++; // 空一行
        Row backupHeaderRow = sheet.createRow(rowNum++);
        backupHeaderRow.createCell(0).setCellValue(windowTitle);

        // 合并 0 到 2 列（即 3 列），并设置居中
        sheet.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 0, 2));

// 创建居中样式
        CellStyle centerStyle = workbook.createCellStyle();
        centerStyle.setAlignment(HorizontalAlignment.CENTER);
        centerStyle.setVerticalAlignment(VerticalAlignment.CENTER);

// 应用样式
        backupHeaderRow.setRowStyle(centerStyle);


        // 下部：材料数据
        rowNum++; // 空一行
        Row dataHeaderRow = sheet.createRow(rowNum++);
        dataHeaderRow.createCell(0).setCellValue("材料名称");
        dataHeaderRow.createCell(1).setCellValue("长度");
        dataHeaderRow.createCell(2).setCellValue("数量");

        for (Map<String, Object> material : materialData) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellValue(material.get("materialName").toString());
            row.createCell(1).setCellValue(Double.parseDouble(material.get("length").toString()));
            row.createCell(2).setCellValue(Integer.parseInt(material.get("quantity").toString()));
        }

        // 写入文件
        workbook.write(response.getOutputStream());

        workbook.close();
    }

    public static void exportCuttingPlan(McpProjects projectInfo,
                                         List<McpWindows> mcpWindows,
                                         List<List<McpMaterialResults>> mcpMaterialResults,
                                         String totalWeightString,
                                         HttpServletResponse response) throws IOException {
        List<String> materialNames = new ArrayList<>();
        ArrayList<HashMap<String, String>> mcpMaterialResultsList = new ArrayList<>();

        for (List<McpMaterialResults> materialResults : mcpMaterialResults) {
            // 将mcpMaterialResults1中的materialLength、materialCount合并成一条信息
            HashMap<String, String> stringObjectHashMap = new HashMap<>();
            for (int i = 0; i < materialResults.size(); i++) {
                McpMaterialResults element = materialResults.get(i);
                if (stringObjectHashMap.containsKey(element.getMaterialName())) {
                    String[] split = stringObjectHashMap.get(element.getMaterialName()).split(" ");
                    String value = stringObjectHashMap.get(element.getMaterialName()) + " ";
                    if (split.length % 2 == 0) {
                        value += "\n";
                    }
                    value = value + element.getMaterialLength().stripTrailingZeros().toPlainString() + "x" + element.getMaterialCount();

                    stringObjectHashMap.put(element.getMaterialName(), value);
                } else {
                    stringObjectHashMap.put(element.getMaterialName(), element.getMaterialLength().stripTrailingZeros().toPlainString() + "x" + element.getMaterialCount());
                }
                materialNames.add(element.getMaterialName());
            }
            mcpMaterialResultsList.add(stringObjectHashMap);

        }
        // 料型去重
        materialNames = materialNames.stream().distinct().collect(Collectors.toList());
        // 总平米数
        BigDecimal pm = new BigDecimal("0");
        for (int i = 0; i < mcpWindows.size(); i++) {
            McpWindows mcpWindows1 = mcpWindows.get(i);
            BigDecimal divide = mcpWindows1.getHeight().multiply(mcpWindows1.getWidth()).multiply(new BigDecimal(mcpWindows1.getQuantity().toString())).divide(new BigDecimal("1000000"));
            pm = pm.add(divide);
        }
//        开始绘制

        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("切割方案");


        // 创建一个单元格样式
        CellStyle cellStyle = workbook.createCellStyle();

        // 设置边框样式
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);

        // 设置边框颜色
        cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());

        CellStyle wrapStyle = workbook.createCellStyle();
        wrapStyle.setWrapText(true); // ✅ 启用自动换行
        wrapStyle.setAlignment(HorizontalAlignment.LEFT);
        wrapStyle.setVerticalAlignment(VerticalAlignment.TOP);

        // 设置边框样式
        wrapStyle.setBorderTop(BorderStyle.THIN);
        wrapStyle.setBorderBottom(BorderStyle.THIN);
        wrapStyle.setBorderLeft(BorderStyle.THIN);
        wrapStyle.setBorderRight(BorderStyle.THIN);

        // 设置边框颜色
        wrapStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
        wrapStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        wrapStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        wrapStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());

        CellStyle wrapStyleR = workbook.createCellStyle();
        wrapStyleR.setWrapText(true); // ✅ 启用自动换行
        wrapStyleR.setAlignment(HorizontalAlignment.RIGHT);
        wrapStyleR.setVerticalAlignment(VerticalAlignment.TOP);

        // 设置边框样式
        wrapStyleR.setBorderTop(BorderStyle.THIN);
        wrapStyleR.setBorderBottom(BorderStyle.THIN);
        wrapStyleR.setBorderLeft(BorderStyle.THIN);
        wrapStyleR.setBorderRight(BorderStyle.THIN);

        // 设置边框颜色
        wrapStyleR.setTopBorderColor(IndexedColors.BLACK.getIndex());
        wrapStyleR.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        wrapStyleR.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        wrapStyleR.setRightBorderColor(IndexedColors.BLACK.getIndex());



        int rowNum = 0;

        Row row = sheet.createRow(rowNum++);
        Cell keyCell = row.createCell(0);
        keyCell.setCellValue("项目名称");
        Cell valueCell = row.createCell(1);
        valueCell.setCellValue(projectInfo.getProjectName());

        row = sheet.createRow(rowNum++);
        keyCell = row.createCell(0);
        keyCell.setCellValue("数据统计");
        valueCell = row.createCell(1);
        valueCell.setCellValue(pm.stripTrailingZeros().toPlainString() + "㎡");

        valueCell = row.createCell(2);
        valueCell.setCellValue(totalWeightString + "kg");

        row = sheet.createRow(rowNum++);
        keyCell = row.createCell(0);
        keyCell.setCellStyle(cellStyle);
        keyCell.setCellValue("门窗名称");
        for (int i = 0; i < mcpWindows.size(); i++) {
            valueCell = row.createCell(1 + i);
            valueCell.setCellStyle(cellStyle);
            valueCell.setCellValue(mcpWindows.get(i).getWindowsName() + "x" + mcpWindows.get(i).getQuantity() + "堂");
            sheet.setColumnWidth(1 + i, 256 * 15); // 材料名称列宽约30字符
        }
        // 添加门窗名称列后面的样式
        valueCell = row.createCell(1 + mcpWindows.size());
        valueCell.setCellStyle(cellStyle);

        row = sheet.createRow(rowNum++);
        keyCell = row.createCell(0);
        keyCell.setCellStyle(cellStyle);
        keyCell.setCellValue("窗型图");
        row.setHeight((short) (256*5));

        for (int i = 0; i < mcpWindows.size(); i++) {
//绘制变量
            if (mcpWindows.get(i).getMcpVariableValueList() != null){
                String collect = mcpWindows.get(i).getMcpVariableValueList().stream()
                        .map(mcpVariableValue -> mcpVariableValue.getVariableName() + "=" + mcpVariableValue.getValue())
                        .collect(Collectors.joining("\n"));

                valueCell = row.createCell(1 + i);
                valueCell.setCellStyle(wrapStyleR);
                valueCell.setCellValue(collect);
            }

//绘制窗型图
            byte[] imageData = ImageUtils.readFile(mcpWindows.get(i).getTypeImage());// 获取图片路径
            if (imageData == null) {
                logger.error("图片不存在");
                continue;
            }
            int pictureIdx = workbook.addPicture(imageData, Workbook.PICTURE_TYPE_PNG);
            CreationHelper helper = workbook.getCreationHelper();
            Drawing<?> drawing = sheet.createDrawingPatriarch();

            ClientAnchor anchor = helper.createClientAnchor();
            anchor.setCol1(1 + i);             // 第二列开始
//            anchor.setCol2(1 + i);             // 占据两列宽度
            anchor.setRow1(rowNum - 1);    // 当前行

            Picture picture = drawing.createPicture(anchor, pictureIdx);

            double scale = getMinScale(imageData, sheet, 1 + i, rowNum - 1);

            // 使用 scale 控制大小，保留偏移
            picture.resize(scale); // 不会清空 dx/dy


        }
        // 添加窗型图列后面的样式
        valueCell = row.createCell(1 + mcpWindows.size());
        valueCell.setCellStyle(cellStyle);

        row = sheet.createRow(rowNum++);
        keyCell = row.createCell(0);
        keyCell.setCellStyle(cellStyle);
        keyCell.setCellValue("型材");
        for (int i = 0; i < mcpWindows.size(); i++) {
            valueCell = row.createCell(1 + i);
            valueCell.setCellStyle(cellStyle);
            valueCell.setCellValue("下料尺寸(mm)");
        }
        valueCell = row.createCell(1 + mcpWindows.size());
        valueCell.setCellStyle(cellStyle);
        valueCell.setCellValue("统计(m)");


        for (int i = 0; i < materialNames.size(); i++) {
            String materialName = materialNames.get(i);

            row = sheet.createRow(rowNum++);
            keyCell = row.createCell(0);
            keyCell.setCellStyle(cellStyle);
            keyCell.setCellValue(materialName);

            for (int j = 0; j < mcpMaterialResultsList.size(); j++) {
                HashMap<String, String> mcpMaterialResult = mcpMaterialResultsList.get(j);
                keyCell = row.createCell(1 + j);
                keyCell.setCellValue(mcpMaterialResult.get(materialName));
                keyCell.setCellStyle(wrapStyle);
            }
            // 统计列
            BigDecimal totle = new BigDecimal("0");
            for (int j = 0; j < mcpMaterialResultsList.size(); j++) {
                HashMap<String, String> mcpMaterialResult = mcpMaterialResultsList.get(j);
                String s = mcpMaterialResult.get(materialName);
                if (s != null) {
                    String[] split = s.split(" ");
                    for (int i1 = 0; i1 < split.length; i1++) {
                        split[i1] = split[i1].replace("x", "*");
                        // split[i1]存储的数学运算式，需进行数学运算
                        Expression expression = new Expression(split[i1]);
                        try {
                            totle = totle.add(expression.evaluate().getNumberValue());
                        } catch (ParseException | EvaluationException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

            }
            // 设置统计列
            keyCell = row.createCell(1 + mcpMaterialResultsList.size());
            keyCell.setCellStyle(cellStyle);
            keyCell.setCellValue(totle.divide(new BigDecimal("1000")).stripTrailingZeros().toPlainString());
        }

        // 写入文件
        workbook.write(response.getOutputStream());

        workbook.close();
    }

    /**
     * 获取图片缩放比例
     * @param imageData
     * @param sheet
     * @param column
     * @param Row
     * @return
     * @throws IOException
     */
    private static double getMinScale(byte[] imageData, Sheet sheet, int column,int Row) throws IOException {
        // 1. 获取图片原始尺寸
        BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageData));
        int imgWidth = bufferedImage.getWidth();
        int imgHeight = bufferedImage.getHeight();

// 2. 获取目标单元格尺寸（例如：列宽 20 字符，行高 5 字符）
        int colWidthUnits = sheet.getColumnWidth(column); // 获取列宽（单位：1/256字符）
        int rowHeightUnits = sheet.getRow(Row).getHeight(); // 获取行高（单位：1/20点）

// 转换单位（近似）
        double targetWidthPx = (double) colWidthUnits / 256 * 7*0.6; // 估算像素（7 是字符宽度近似值）
        double targetHeightPx = (double) rowHeightUnits / 20 * 1.33*0.9; // 估算像素（1.33 是点转像素）

// 3. 计算缩放比例（保持比例）
        double scale = Math.min(
                (double) targetWidthPx / imgWidth,
                (double) targetHeightPx / imgHeight
        );
        return scale;
    }
}
